package com.taoes.simpledocker.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.model.Network;
import com.github.dockerjava.api.model.PruneType;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.taoes.simpledocker.config.DockerClientFactory;
import com.taoes.simpledocker.controller.network.NewNetworkRequest;
import com.taoes.simpledocker.model.ResponseModel;
import com.taoes.simpledocker.model.Role;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 网络控制器接口
 *
 * @author 枕上江南 zhoutao825638@vip.qq.com
 * @date 2021/12/4 11:35 下午
 */
@Api(tags = "Docker网络管理")
@ApiSort(value = 5)
@RestController
@RequestMapping("/api/network")
@RequiredArgsConstructor
public class NetWorkController {

    private final DockerClientFactory clientFactory;

    @ApiOperation("网络列表")
    @SaCheckPermission(value = "network:query", orRole = Role.ADMIN_ROLE_NAME)
    @GetMapping("/list")
    public ResponseModel<List<Network>> list() {
        DockerClient client = clientFactory.get();
        final List<Network> exec = client.listNetworksCmd().exec();
        return ResponseModel.ok(exec);
    }

    @ApiOperation("删除网络")
    @SaCheckPermission(value = "network:remove", orRole = Role.ADMIN_ROLE_NAME)
    @PostMapping("/remove/{networkId}")
    public ResponseModel deleteNetwork(@PathVariable String networkId) {
        DockerClient client = clientFactory.get();

        if ("bridge".equals(networkId) || "none".equals(networkId) || "host".equals(networkId)) {
            return ResponseModel.fail("该网络不可删除");
        }
        try {
            client.removeNetworkCmd(networkId).exec();
        } catch (Exception e) {
            throw new RuntimeException("删除网络失败:" + e.getMessage());
        }
        return ResponseModel.ok(Boolean.TRUE);
    }

    @ApiOperation("新建网络")
    @SaCheckPermission(value = "network:new", orRole = Role.ADMIN_ROLE_NAME)
    @PostMapping("/newNetwork")
    public ResponseModel newNetwork(@RequestBody NewNetworkRequest network) {
        DockerClient client = clientFactory.get();

        try {
            client.createNetworkCmd()
                    .withName(network.getName())
                    .withDriver(network.getDriver())  // default:local  /  none
                    .withIpam(network.getIpam())    // default:null
                    .withInternal(network.getInternal()) // default:false
                    .withEnableIpv6(network.getEnableIPv6()) // default:false
                    .withOptions(network.getOptions()) // default:null
                    .exec();

        } catch (Exception e) {
            throw new RuntimeException("删除网络失败:" + e.getMessage());
        }
        return ResponseModel.ok(Boolean.TRUE);
    }


    @ApiOperation("清理无用网络")
    @SaCheckPermission(value = "image:prune", orRole = Role.ADMIN_ROLE_NAME)
    @PostMapping("/prune")
    public ResponseModel<Boolean> purge() {
        DockerClient client = clientFactory.get();
        client.pruneCmd(PruneType.NETWORKS).exec();
        return ResponseModel.ok(Boolean.TRUE);
    }
}
